package com.corejsf;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;
/**
 *
 * Scheduler class is used by each user to generate a unique current timesheet,
 * and keeps track of the timesheet's history.
 *
 * @author Victor Lu
 * @version 1.0
 *
 */
public class Scheduler implements Serializable {
    /**
     *  serialVersionUID.
     */
    private static final long serialVersionUID = 2269996014365436200L;
    /**
     * timeSheet - Arraylist of Timesheet beans (which are the displayed rows).
     */
    private ArrayList<Timesheet> timeSheets;
    /**
     * oldTimeSheets - Arraylist of Arraylists of Timesheets. Entire Table of a
     * Timesheet is stored to an old timesheet to store into the history.
     */
    private ArrayList<ArrayList<Timesheet>> oldTimeSheets = new ArrayList<ArrayList<Timesheet>>();
    /**
     * Initial week number that keeps stays the same. Week number being viewed in the OldTimeSheets view.
     */
    private int oldWeekNum = 1;
    /**
     * LinkedHashMap holds the values of the dropdown list of weeks.
     */
    private LinkedHashMap<String, Integer> weekCount;
    
    /**
     * DataSource for JBoss AS 7.1 connection pool.
     */
    @Resource(mappedName = "java:jboss/datasources/vvdb")
    private DataSource dataSource;

	/**
     * Set by User when it instantiates its scheduler.
     */
    private User owner;

    /**
     * Constructor.
     */
    public Scheduler() {
    }

    /**
     * In case there are no values, the timesheet is initialized with
     * 5 empty rows.
     * @return a set of timeSheets.
     */

    @PostConstruct
    public void loadCurrentTimeSheet() {
        Connection connection = null;
        PreparedStatement stmt = null;
        try {
            try {
            	Timesheet temp;
                connection = dataSource.getConnection();
                try {
                    int empNo = owner.getEmployeeNumber();
                    int weekNo = owner.getWeekNum();
                	stmt = connection.prepareStatement("SELECT * FROM Timesheets WHERE EmployeeNumber = ? AND WeekNumber = ?");
                    stmt.setInt(1, empNo);
                    stmt.setInt(2, weekNo);
                    ResultSet result = stmt.executeQuery();
                    while (result.next()) {
                        temp = new Timesheet();
                        temp.setProject(result.getDouble("project"));
                        temp.setWp(result.getString("wp"));
                        temp.setTotal(result.getDouble("total"));
                        temp.setSat(result.getDouble("sat"));
                        temp.setSun(result.getDouble("sun"));
                        temp.setMon(result.getDouble("mon"));
                        temp.setTue(result.getDouble("tue"));
                        temp.setWed(result.getDouble("wed"));
                        temp.setThu(result.getDouble("thu"));
                        temp.setFri(result.getDouble("fri"));
                        temp.setNotes(result.getString("notes"));
                        timeSheets.add(temp);
                    }
                    
                    //
                    for(int i = 0; i < weekNo - 1; i++){
                    	oldTimeSheets.add(new ArrayList<Timesheet>());
                    }
                    
                    stmt = connection.prepareStatement("SELECT * FROM Timesheets WHERE EmployeeNumber = ? AND WeekNumber != ?");
                    stmt.setInt(1, empNo);
                    stmt.setInt(2, weekNo);
                    result = stmt.executeQuery();
                    int pastWeekNo;
                    while (result.next()) {
                    	pastWeekNo = result.getInt("WeekNumber");
                    	
                        temp = new Timesheet();
                        temp.setProject(result.getDouble("project"));
                        temp.setWp(result.getString("wp"));
                        temp.setTotal(result.getDouble("total"));
                        temp.setSat(result.getDouble("sat"));
                        temp.setSun(result.getDouble("sun"));
                        temp.setMon(result.getDouble("mon"));
                        temp.setTue(result.getDouble("tue"));
                        temp.setWed(result.getDouble("wed"));
                        temp.setThu(result.getDouble("thu"));
                        temp.setFri(result.getDouble("fri"));
                        temp.setNotes(result.getString("notes"));
                        oldTimeSheets.get(pastWeekNo - 1).add(temp);
                    }
                
                } finally {
                    if (stmt != null) {
                        stmt.close();
                    }

                }
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        } catch (SQLException ex) {
            System.out.println("Error in loadUsers");
            ex.printStackTrace();
        }        
    }
    
  
    public final ArrayList<Timesheet> getTimeSheets() {
        if (timeSheets == null) {
        	timeSheets = new ArrayList<Timesheet>();
            for (int i = 0; i < 5; i++) {
            	timeSheets.add(new Timesheet());
            }
        }
        return timeSheets;
    }

    /**
     * Sets the current timesheet.
     * @param timeSheet a timesheet for that week.
     */
    public final void setTimeSheets(final ArrayList<Timesheet> timeSheets) {
        this.timeSheets = timeSheets;
    }

    /**
     * Grabs the old timesheets that have been previously submitted.
     *
     * @return all timesheets
     */
    public final ArrayList<ArrayList<Timesheet>> getOldTimeSheets() {
        return oldTimeSheets;
    }

    /**
     * Pushes the timesheet into the oldTimeSheets arrayList.
     * Generates 5 new timeSheets to display
     * for the week.
     * Returns the editSchedulePage once again.
     * @return navigation outcome string
     */
    public final String nextWeek() {
        getOldTimeSheets().add(getTimeSheets());
        owner.incrWeekNum();
        timeSheets = null;
        getTimeSheets();
        return "editSchedule";
    }
    
    /**
     * Adds a row to the current timeSheet.
     */
    public final void addRow() {
        if (timeSheets.size() < 10) {
        	timeSheets.add(new Timesheet());
        }
    }

    /**
     * Deletes a row from the current timeSheet.
     */
    public final void deleteRow() {
        if (timeSheets.size() != 0) {
        	timeSheets.remove(timeSheets.size() - 1);
        }
    }
    
    public final void save() {
        Connection connection = null;
        PreparedStatement stmt = null;
        try {
            try {
                if (dataSource == null){
                    System.out.println("WE ARE FUCKED");
                }
                connection = dataSource.getConnection();
                try {
                    stmt = connection.prepareStatement(
                            "DELETE FROM Timesheets" +
                    		"WHERE EmployeeNumber = ?" +
                            "AND WeekNumber = ?");
                    stmt.setDouble(1, owner.getEmployeeNumber());
                    stmt.setDouble(2, owner.getWeekNum());
                    stmt.executeUpdate();
                            
                } finally {
                    if (stmt != null) {
                        stmt.close();
                    }

                }
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        } catch (SQLException ex) {
            System.out.println("Error in save(updatedTimesheets)");
            ex.printStackTrace();
        }
        
        for(int i=0; i<timeSheets.size(); i++) {
            if(timeSheets.get(i).getProject() != 0 && timeSheets.get(i).getWp() != null) {
                try {
                    try {
                        
                        connection = dataSource.getConnection();
                        try {
                            stmt = connection.prepareStatement(
                                    "INSERT INTO Timesheets" +
                                    "(EmployeeNumber, WeekNumber, Project, WP, Total, Sat, Sun, Mon, Tue, Wed, Thu, Fri, Notes)" +
                                    "VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                            
                            stmt.setDouble(1, owner.getEmployeeNumber());
                            stmt.setDouble(2, owner.getWeekNum());
                            stmt.setDouble(3, timeSheets.get(i).getProject());
                            stmt.setString(4, timeSheets.get(i).getWp());
                            stmt.setDouble(5, timeSheets.get(i).getTotal());                         
                            stmt.setDouble(6, timeSheets.get(i).getSat());                       
                            stmt.setDouble(7, timeSheets.get(i).getSun());                       
                            stmt.setDouble(8, timeSheets.get(i).getMon());                       
                            stmt.setDouble(9, timeSheets.get(i).getTue());                       
                            stmt.setDouble(10, timeSheets.get(i).getWed());                       
                            stmt.setDouble(11, timeSheets.get(i).getThu());                       
                            stmt.setDouble(12, timeSheets.get(i).getFri()); 
                            stmt.setString(13, timeSheets.get(i).getNotes());
                            stmt.executeUpdate();
                            
                        } finally {
                            if (stmt != null) {
                                stmt.close();
                            }

                        }
                    } finally {
                        if (connection != null) {
                            connection.close();
                        }
                    }
                } catch (SQLException ex) {
                    System.out.println("Error in save(updatedTimesheets)");
                    ex.printStackTrace();
                }
                
            }
        }
        
        
    }
    
    /**
     * Sums up the 'Total' columnn.
     *
     * @return the total of the column.
     */
    public final double getColumnTotal() {
        double columnTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            columnTotal += timeSheets.get(i).getTotal();
        }
        return columnTotal;
    }

    /**
     * Sums up the 'Sat' column.
     *
     * @return the total of the column.
     */
    public final double getSatTotal() {
        double satTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            satTotal += timeSheets.get(i).getSat();
        }
        return satTotal;
    }

    /**
     * Sums up the 'Sun' column.
     *
     * @return the total of the column.
     */
    public final double getSunTotal() {
        double sunTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            sunTotal += timeSheets.get(i).getSun();
        }
        return sunTotal;
    }

    /**
     * Sums up the 'Mon' column.
     *
     * @return the total of the column.
     */
    public final double getMonTotal() {
        double monTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            monTotal += timeSheets.get(i).getMon();
        }
        return monTotal;
    }

    /**
     * Sums the 'Tue' column.
     *
     * @return the total of the column.
     */
    public final double getTueTotal() {
        double tueTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            tueTotal += timeSheets.get(i).getTue();
        }
        return tueTotal;
    }

    /**
     * Sums up the 'Wed' column.
     *
     * @return the total of the column.
     */
    public final double getWedTotal() {
        double wedTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            wedTotal += timeSheets.get(i).getWed();
        }
        return wedTotal;
    }

    /**
     * Sums up the 'Thu' column.
     *
     * @return the total of the column.
     */
    public final double getThuTotal() {
        double thuTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            thuTotal += timeSheets.get(i).getThu();
        }
        return thuTotal;
    }

    /**
     * Sums up the 'Fri' column.
     *
     *@return the total of the column.
     */
    public final double getFriTotal() {
        double friTotal = 0;
        for (int i = 0; i < timeSheets.size(); i++) {
            friTotal += timeSheets.get(i).getFri();
        }
        return friTotal;
    }

    /**
     * Gets the current week number.
     *
     * @return weekNum.
     */
    public final int getWeekNum() {
    	return owner.getWeekNum();
    }

    /**
     * Sets the current week number.
     *
     * @param weekNum current week number
     */
    public final void setWeekNum(final int weekNum) {
    	owner.setWeekNum(weekNum);
    }

    /**
     * Adds the current week into the dropdown list represented
     * by a linked hash map.
     *
     * @return week count.
     */
    public final LinkedHashMap<String, Integer> getWeekCount() {
        int weeks = getWeekNum() - 1;
        weekCount = new LinkedHashMap<String, Integer>();
        for (int i = 1; i <= weeks; i++) {
            this.weekCount.put("Week " + i, i);
        }
        return weekCount;
    }

    /**
     * Gets the old week number.
     *
     * @return oldWeekNum
     */
    public final int getOldWeekNum() {
        return oldWeekNum;
    }

    /**
     * Sets the old week number.
     * @param oldWeekNum old week number
     */
    public final void setOldWeekNum(final int oldWeekNum) {
        this.oldWeekNum = oldWeekNum;
    }

    /**
     * Get the values of the old week.
     *
     * This function only called if oldTimeSheets.size() != 0
     * see oldTimeSheets.xhtml
     *
     * @return the stored TimeSheets
     */
    public final ArrayList<Timesheet> getOldWeek() {
        return oldTimeSheets.get(oldWeekNum - 1);
    }


    public void setOwner(User owner) {
		this.owner = owner;
	}
}
